﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CRMBiz;
using CRMFramework;
using System.Net;
using Newtonsoft.Json.Linq;
using System.Configuration;
using System.Threading;

namespace CRMWinApp.VerifyEmail
{
    public partial class VerifyEmail : Form
    {
        Thread VerifyEmail_thread;
        delegate void DelegateETA(string text);
        delegate void DelegateError(string text);
        delegate void DelegatePass(string text);
        delegate void DelegateFail(string text);
        DelegateETA ETADelegate;
        DelegateError ErrorDelegate;
        DelegatePass PassDelegate;
        DelegateFail FailDelegate;
        public VerifyEmail()
        {
            InitializeComponent();
        }

        private void VerifyEmail_Load(object sender, EventArgs e)
        {
            ETADelegate = SetETADelegate;
            ErrorDelegate = SetErrorDelegate;
            PassDelegate = SetPassDelegate;
            FailDelegate = SetFailDelegate;
        }

        private void btnValidate_Click(object sender, EventArgs e)
        {
            if (txtFromID.Text != "" && txtToID.Text != "")
            {
                VerifyEmail_thread = new Thread(() => checkEmailValidation());
                VerifyEmail_thread.Start();
            }
            else
            {
                lblError.Text = "From and To field are required";
            }
        }

        private void checkEmailValidation()
        {
            int cnt = 0;
            int totalPass = 0;
            int totalfailed = 0;
            bool isVerified = false, isLimit = false;
            string email = string.Empty;
            string apiUrl = ConfigurationManager.AppSettings["apiurl"];
            string apiUsername = ConfigurationManager.AppSettings["apiUsername"];
            string apiPassword = ConfigurationManager.AppSettings["apiPassword"];
            WebClient webClient = null;
            try
            {
                DataSet ds = EmailVerificationHandler.getClientListVerifyEmail(txtFromID.Text, txtToID.Text);
                DateTime starttime = DateTime.Now;
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    this.BeginInvoke(this.ETADelegate, CalculateEta(starttime, ds.Tables[0].Rows.Count, ++cnt));

                    //for primary mail
                    if (int.Parse(dr.ItemArray[3].ToString()) == -1)
                    {
                        email = dr.ItemArray[1].ToString();
                        if (string.IsNullOrEmpty(email))
                        {
                            totalfailed++;
                            DBhelper.ExecuteNonQuery("update crm_contact set validate_email1=0 where contactid=" + dr.ItemArray[0]);
                            this.BeginInvoke(this.FailDelegate, totalfailed.ToString());
                        }
                        else
                        {
                            webClient = new WebClient();
                            string result = webClient.DownloadString(string.Format("{0}usr={1}&pwd={2}&check={3}", apiUrl, apiUsername, apiPassword, email));

                            JObject objJSON = default(JObject);
                            objJSON = JObject.Parse(result);

                            if (objJSON["verify_status"] != null)
                            {
                                isVerified = Convert.ToBoolean(Convert.ToInt32(objJSON["verify_status"].ToString())) ? true : false;
                                if (isVerified)
                                {
                                    totalPass++;
                                    DBhelper.ExecuteNonQuery("update crm_contact set validate_email1=1 where contactid=" + dr.ItemArray[0]);
                                    this.BeginInvoke(this.PassDelegate, totalPass.ToString());
                                }
                                else
                                {
                                    totalfailed++;
                                    DBhelper.ExecuteNonQuery("update crm_contact set validate_email1=0 where contactid=" + dr.ItemArray[0]);
                                    this.BeginInvoke(this.FailDelegate, totalfailed.ToString());
                                }
                            }
                            else
                            {
                                this.BeginInvoke(this.ErrorDelegate, objJSON["limit_desc"].ToString());
                                isLimit = true;
                                break;
                            }
                        }
                    }
                    //for secondary mail
                    if (int.Parse(dr.ItemArray[4].ToString()) == -1)
                    {
                        email = dr.ItemArray[2].ToString();
                        if (string.IsNullOrEmpty(email))
                        {
                            totalfailed++;
                            DBhelper.ExecuteNonQuery("update crm_contact set validate_email2=0 where contactid=" + dr.ItemArray[0]);
                            this.BeginInvoke(this.FailDelegate, totalfailed.ToString());
                        }
                        else
                        {
                            webClient = new WebClient();
                            string result = webClient.DownloadString(string.Format("{0}usr={1}&pwd={2}&check={3}", apiUrl, apiUsername, apiPassword, email));

                            JObject objJSON = default(JObject);
                            objJSON = JObject.Parse(result);

                            if (objJSON["verify_status"] != null)
                            {
                                isVerified = Convert.ToBoolean(Convert.ToInt32(objJSON["verify_status"].ToString())) ? true : false;
                                if (isVerified)
                                {
                                    totalPass++;
                                    DBhelper.ExecuteNonQuery("update crm_contact set validate_email2=1 where contactid=" + dr.ItemArray[0]);
                                    this.BeginInvoke(this.PassDelegate, totalPass.ToString());
                                }
                                else
                                {
                                    totalfailed++;
                                    DBhelper.ExecuteNonQuery("update crm_contact set validate_email2=0 where contactid=" + dr.ItemArray[0]);
                                    this.BeginInvoke(this.FailDelegate, totalfailed.ToString());
                                }
                            }
                            else
                            {
                                this.BeginInvoke(this.ErrorDelegate, objJSON["limit_desc"].ToString());
                                isLimit = true;
                                break;
                            }
                        }
                    }
                }

                this.BeginInvoke(this.PassDelegate, totalPass.ToString());
                this.BeginInvoke(this.FailDelegate, totalfailed.ToString());
                this.BeginInvoke(this.ETADelegate, "");
                if (isLimit == false)
                    this.BeginInvoke(this.ErrorDelegate, "Email Verify Successfully...");
            }
            catch (Exception ex)
            {
                this.BeginInvoke(this.ErrorDelegate, ex.Message);
            }
        }

        void SetETADelegate(string text)
        {
            string[] time = text.Split(':');
            if (time.Length > 1)
                lbltime.Text = time[0].ToString() + " hours  " + time[1].ToString() + " mins " + time[2].ToString() + " seconds";
            else
                lbltime.Text = "";
        }

        void SetPassDelegate(string text)
        {
            lblPass.Text = text;
        }

        void SetFailDelegate(string text)
        {
            lblFailed.Text = text;
        }

        void SetErrorDelegate(string text)
        {
            lblError.Text = text;
        }

        /// <summary>
        /// Calculates the eta.
        /// </summary>
        /// <param name="processStarted">When the process started</param>
        /// <param name="totalElements">How many items are being processed</param>
        /// <param name="processedElements">How many items are done</param>
        /// <returns>A string representing the time left</returns>
        private string CalculateEta(DateTime processStarted, int totalElements, int processedElements)
        {
            float itemsPerSecond = (float)((totalElements - processedElements) * 0.1 / processedElements);
            int secondsRemaining = (int)(itemsPerSecond * 60);
            return new TimeSpan(0, 0, secondsRemaining).ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            txtFromID.Text = string.Empty;
            txtToID.Text = string.Empty;
            lblError.Text = string.Empty;
            lblFailed.Text = string.Empty;
            lblPass.Text = string.Empty;
            lbltime.Text = string.Empty;
        }
    }
}
